package com.credithc.signature.manager.service;

import com.credithc.baseserv.pageHelper.PageInfo;
import com.credithc.signature.common.constant.ManagerConstant;
import com.credithc.signature.common.mapper.ChannelMapper;
import com.credithc.signature.common.mapper.SignatureLogMapper;
import com.credithc.signature.common.po.Channel;
import com.credithc.signature.common.po.OfficialSealTemplate;
import com.credithc.signature.common.po.SealInfo;
import com.credithc.signature.common.po.SignatureLog;
import com.credithc.signature.common.po.Template;
import com.credithc.signature.common.ro.manager.SignLogRo;
import com.credithc.signature.common.service.DictionaryService;
import com.credithc.signature.common.service.OfficialSealTemplateService;
import com.credithc.signature.common.service.SealInfoService;
import com.credithc.signature.common.service.SignatureLogService;
import com.credithc.signature.common.service.TemplateService;
import com.credithc.signature.common.utils.DateUtil;
import com.credithc.signature.common.vo.manager.SignLogPreviewVo;
import com.credithc.signature.common.vo.manager.SignLogVo;
import com.credithc.signature.manager.client.AuthClient;
import com.credithc.signature.manager.ro.ProductRo;
import com.credithc.signature.manager.vo.CompanyProductVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 描述：签章记录页面服务层<br/>
 * 作者：sunyang
 * 创建：2019/6/19 10:17
 * 版本：v1.0.0<br/>
 */
@Slf4j
@Service
public class SignLogService {

    @Autowired
    private TemplateService templateService;

    @Autowired
    private SignatureLogService signatureLogService;

    @Autowired
    private DictionaryService dictionaryService;

    @Autowired
    private SignatureLogMapper signatureLogMapper;

    @Autowired
    private OfficialSealTemplateService officialSealTemplateService;

    @Autowired
    private SealInfoService sealInfoService;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private ChannelMapper channelMapper;

    @Autowired
    private AuthClient authClient;

    private static final String TEMPLATE_NAME = "template_name";
    private static final String SEAL_TYPE = "seal_type";

    public SignLogPreviewVo querySignLogPreview(Long id, Date dateFromStr) {
        SignLogPreviewVo signLogPreviewVo = signatureLogMapper.selectSignLogPreviewVo(id,dateFromStr,DateUtil.getBeforeDate(1,dateFromStr));
        if (signLogPreviewVo.getSignType() != ManagerConstant.PERSONAL) {
            OfficialSealTemplate officialSealTemplate = new OfficialSealTemplate();
            officialSealTemplate.setTemplateNo(signLogPreviewVo.getTemplateNO());
            List<OfficialSealTemplate> poList = officialSealTemplateService.selectByExample(officialSealTemplate);
            if (poList != null && !poList.isEmpty()) {
                List<String> sealCodes = poList.stream().map(item -> item.getOfficialSealCode()).collect(Collectors.toList());
                List<SealInfo> sealInfos = sealInfoService.selectBySealCodeList(sealCodes);
                List<String> keywords = sealInfos.stream().map(sealInfo -> sealInfo.getKeyWords()).collect(Collectors.toList());
                signLogPreviewVo.setOfficialKeyWords(keywords);
            }
        }
        String signTypeName = dictionaryService.selectOneByTypeAndCode(ManagerConstant.SEAL_TYPE, signLogPreviewVo.getSignType());
        signLogPreviewVo.setSignType(signTypeName);
        String sourceName = dictionaryService.selectOneByTypeAndCode(ManagerConstant.RESOURCE_TYPE, signLogPreviewVo.getTemplateResource());
        signLogPreviewVo.setTemplateResource(sourceName);
        return signLogPreviewVo;
    }

    public PageInfo<SignLogVo> querySignLogAll(SignLogRo signLogRo, String token) {
        Integer companyId = signLogRo.getCompanyId();
        String code = signLogRo.getCode();
        Integer userId = signLogRo.getUserId();
        CompanyProductVo productMap = companyService.getProductMap(code, companyId, userId);
        List<String> channelIds = productMap.getChannelIds();
        Map<String, ProductRo> proMap = productMap.getProMap();
        if (companyId != null || userId != null) {
            if (channelIds.size() < 1) {
                return new PageInfo<>(new ArrayList<>(), 0, 0, 0);
            } else {
                signLogRo.setChannelIds(channelIds);
            }
        }

        List<SignLogVo> signLogVos = signatureLogMapper.selectAllSelective(signLogRo.getRequestSN(), signLogRo.getTemplateNo(),
                signLogRo.getChannelIds(), signLogRo.getSignStatus(), signLogRo.getNeedSign(), signLogRo.getStartTime(), signLogRo.getEndTime(),
                signLogRo.getTemplateName(), signLogRo.getSignType(), (signLogRo.getPageSize() * (signLogRo.getPageNo() - 1)),
                signLogRo.getPageSize(), signLogRo.getCode());

        int count = signatureLogMapper.selectAllCountSelective(signLogRo.getRequestSN(), signLogRo.getTemplateNo(),
                signLogRo.getChannelIds(), signLogRo.getSignStatus(), signLogRo.getNeedSign(), signLogRo.getStartTime(), signLogRo.getEndTime(),
                signLogRo.getTemplateName(), signLogRo.getSignType(), signLogRo.getCode());

        formatSignLogVos(signLogVos);
        return new PageInfo<>(signLogVos, count, signLogRo.getPageNo(), signLogRo.getPageSize());
    }

    private void formatSignLogVos(List<SignLogVo> signLogVos) {
        signLogVos.forEach(signLogVo -> {
            String sealTypeName = dictionaryService.selectOneByTypeAndCode(ManagerConstant.SEAL_TYPE, String.valueOf(signLogVo.getSealType()));
            Channel channel = channelMapper.selectByPrimaryKey(signLogVo.getChannelId());
            signLogVo.setChannelNo(channel.getChannelNo());
            signLogVo.setSealType(sealTypeName);
            signLogVo.setNeedSign("0".equals(signLogVo.getNeedSign()) ? "否" : "是");
            signLogVo.setThirdPartyChannel("0".equals(signLogVo.getThirdPartyChannel()) ? "中金" : "懒猫");
            signLogVo.setSignTime(DateUtil.getDefaultAppointDateStr(signLogVo.getCreateTime()));
            signLogVo.setSignatureStatus(Integer.valueOf(signLogVo.getSignStatus()));
            String signStatus = dictionaryService.selectOneByTypeAndCode(ManagerConstant.SIGN_STATUS, signLogVo.getSignStatus().toString());
            signLogVo.setSignStatus(signStatus);
            //回调状态
            if (StringUtils.isNotEmpty(signLogVo.getSuccessCallCode())) {
                String name = dictionaryService.selectOneByTypeAndCode(ManagerConstant.CALL_STATUS, signLogVo.getSuccessCallCode());
                signLogVo.setCallbackName(name);
            }
        });
    }

    private void getChannleNosByTenantName(SignLogRo signLogRo, Set<String> channelNOs) {
        if (!StringUtils.isBlank(signLogRo.getTenantName())) {
            // 调用云平台查出channelNo list
            PageInfo<ProductRo> productList = companyService.getProductList(null);
            if (productList != null) {
                List<ProductRo> products = productList.getList();
                List<ProductRo> collect = products.stream().filter(productRo -> productRo.getCompanyName() != null &&
                        productRo.getCompanyName().contains(signLogRo.getTenantName())
                ).collect(Collectors.toList());

                if (collect != null && !collect.isEmpty()) {
                    List<String> codes = collect.stream().map(productRo -> productRo.getCode()).collect(Collectors.toList());
                    channelNOs.addAll(codes);
                }
            }
        }
    }

    private void getChannelNosByChannelAdminName(SignLogRo signLogRo, Set<String> channelNOs) {
        if (!StringUtils.isBlank(signLogRo.getChannelAdmin())) {
            // 调用云平台查出channelNo list
            PageInfo<ProductRo> productList = companyService.getProductList(null);
            if (productList != null) {
                List<ProductRo> products = productList.getList();
                List<ProductRo> collect = products.stream().filter(productRo -> productRo.getUserName() != null &&
                        productRo.getUserName().contains(signLogRo.getChannelAdmin())
                ).collect(Collectors.toList());

                if (collect != null && !collect.isEmpty()) {
                    List<String> codes = collect.stream().map(productRo -> productRo.getCode()).collect(Collectors.toList());
                    channelNOs.addAll(codes);
                }
            }
        }
    }

    private void getChannelNosByChannelName(SignLogRo signLogRo, Set<String> channelNOs) {
        if (!StringUtils.isBlank(signLogRo.getChannelName())) {
            // 调用云平台查出channelNo list
            PageInfo<ProductRo> productList = companyService.getProductList(null);
            if (productList != null) {
                List<ProductRo> products = productList.getList();
                List<ProductRo> collect = products.stream().filter(productRo -> productRo.getProductName() != null &&
                        productRo.getProductName().contains(signLogRo.getChannelName())
                ).collect(Collectors.toList());

                if (collect != null && !collect.isEmpty()) {
                    List<String> codes = collect.stream().map(productRo -> productRo.getCode()).collect(Collectors.toList());
                    channelNOs.addAll(codes);
                }
            }
        }
    }

    private List<Integer> getSignStatusList(SignLogRo signLogRo) {
        List<Integer> signStatusList = new ArrayList<>();
        Integer signStatus = signLogRo.getSignStatus();
        if (signStatus != null && signStatus == 1) {
            signStatusList.add(0);
            signStatusList.add(1);
        } else if (signStatus != null && signStatus == 2) {
            signStatusList.add(2);
        } else if (signStatus != null && signStatus == 3) {
            signStatusList.add(3);
        }
        return signStatusList;
    }

    /**
     * 分页的另种实现，先留存，以备复合查询效率低时替换
     *
     * @param signLogRo
     * @return
     */
    @Deprecated
    public PageInfo<SignLogVo> querySignLogAllCopy(SignLogRo signLogRo) {
        Example example = new Example(SignatureLog.class);
        example.setDistinct(false);
        Example.Criteria criteria = example.createCriteria();
        if (!StringUtils.isBlank(signLogRo.getRequestSN())) {
            criteria.andEqualTo(SignLogRo.REQUEST_SN, signLogRo.getRequestSN());
        }
        Set<String> templateNOs = new HashSet<>();
        if (!StringUtils.isBlank(signLogRo.getTemplateName())) {
            Example templateExample = new Example(Template.class);
            templateExample.setDistinct(false);
            Example.Criteria templateCriteria = templateExample.createCriteria();
            templateCriteria.andLike(SignLogService.TEMPLATE_NAME, signLogRo.getTemplateName());
            List<Template> templates = templateService.selectByExample(templateExample);
            if (templates != null && !templates.isEmpty()) {
                List<String> collect = templates.stream().map(template -> template.getTemplateNo()).collect(Collectors.toList());
                templateNOs.addAll(collect);
            }
        }
        if (signLogRo.getSignType() != null && signLogRo.getSignType() != 0) {
            Example templateExample = new Example(Template.class);
            templateExample.setDistinct(false);
            Example.Criteria templateCriteria = templateExample.createCriteria();
            templateCriteria.andEqualTo(SignLogService.SEAL_TYPE, signLogRo.getSignType());
            List<Template> templates = templateService.selectByExample(templateExample);
            if (templates != null && !templates.isEmpty()) {
                List<String> collect = templates.stream().map(template -> template.getTemplateNo()).collect(Collectors.toList());
                templateNOs.addAll(collect);
            }
        }
        if (!StringUtils.isBlank(signLogRo.getTemplateNo())) {
            templateNOs.add(signLogRo.getTemplateNo());
        }
        if (templateNOs != null && !templateNOs.isEmpty()) {
            criteria.andIn(SignLogRo.TEMPLATE_NO, templateNOs);
        }
        if (signLogRo.getSignStatus() != null) {
            criteria.andEqualTo(SignLogRo.SIGN_STATUS, signLogRo.getSignStatus());
        }
        if (signLogRo.getNeedSign() != null) {
            criteria.andEqualTo(SignLogRo.IS_SEAL, signLogRo.getNeedSign());
        }
        Set<String> channelNOs = new HashSet<>();
        if (!StringUtils.isBlank(signLogRo.getChannelName())) {
            // 调用云平台查出channelNo list
        }
        if (!StringUtils.isBlank(signLogRo.getChannelAdmin())) {
            // 调用云平台查出channelNo list
        }
        if (!StringUtils.isBlank(signLogRo.getTenantName())) {
            // 调用云平台查出channelNo list
        }
        if (channelNOs != null && !channelNOs.isEmpty()) {
            criteria.andIn(SignLogRo.CHANNEL_NO, channelNOs);
        }
        if (signLogRo.getStartTime() != null) {
            criteria.andGreaterThan(SignLogRo.CREATE_TIME, signLogRo.getStartTime());
        }
        if (signLogRo.getEndTime() != null) {
            criteria.andGreaterThan(SignLogRo.CREATE_TIME, signLogRo.getEndTime());
        }
        RowBounds rowBounds = new RowBounds(signLogRo.getPageSize() * (signLogRo.getPageNo() - 1), signLogRo.getPageSize());
        List<SignatureLog> signatureLogs = signatureLogService.selectByExampleAndRowBounds(example, rowBounds);
        int count = signatureLogService.selectCountByExample(example);
        List<SignLogVo> data = signatureLogs.stream().map(signatureLog -> {
            SignLogVo signLogVo = new SignLogVo();
            signLogVo.setRequestSN(signatureLog.getRequestSn());
            signLogVo.setTemplateNo(signatureLog.getTemplateNo());
            Template template = templateService.selectByTemplateNo(signatureLog.getTemplateNo());
            signLogVo.setTemplateName(template.getTemplateName());
            String seayTypeName = dictionaryService.selectOneByTypeAndCode(ManagerConstant.SEAL_TYPE, String.valueOf(template.getSealType()));
            signLogVo.setSealType(seayTypeName);
            signLogVo.setNeedSign(signatureLog.getIsSeal() ? "否" : "是");
            signLogVo.setSignTime(DateUtil.getDefaultAppointDateStr(signatureLog.getCreateTime()));
            signLogVo.setLastTime(signatureLog.getLastTime());
            signLogVo.setCallBackTimes(signatureLog.getFailCallNum());
            String signStatus = dictionaryService.selectOneByTypeAndCode(ManagerConstant.SIGN_STATUS, signatureLog.getSignStatus().toString());
            signLogVo.setSignStatus(signStatus);
            signLogVo.setCallbackUrl(signatureLog.getCallbackUrl());
            return signLogVo;
        }).collect(Collectors.toList());
        PageInfo<SignLogVo> pageInfo = new PageInfo<>(data, count, signLogRo.getPageNo(), signLogRo.getPageSize());
        return pageInfo;
    }

}
